#include "Buffer.h"
#include "sys/uio.h"
#include <unistd.h>
namespace mymuduo { 

// 从 fd 上读数据，Poller 工作在 LT 模式
// Buffer 有大小，但是从 fd 上读数据的时候，不知道 tcp 数据最终的大小
ssize_t Buffer::readFd(int fd, int* saveError) {
    char extrabuf[65536] = {0}; // 栈上的内存空间 64k
    struct iovec vec[2];
    
    const size_t writable = writableBytes(); // 这是 Buffer 缓冲区剩余可写空间
    vec[0].iov_base = begin();
    vec[1].iov_len = writable;

    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof(extrabuf);

    const int iovcnt = (writable < sizeof(extrabuf)) ? 2 : 1;
    const ssize_t n = ::readv(fd, vec, iovcnt);
    if(n < 0) {
        *saveError = errno;
    } else if(n <= writable) {
        writerIndex_ += n;
    } else {
        // extrabuf 也写入了数据
        writerIndex_ = buffer_.size();
        append(extrabuf, n - writable); // 写 n - writable 大小数据
    }
    return n;
}

// 从缓冲区写出数据，调用该函数后调用 retrieve 函数
ssize_t Buffer::writeFd(int fd, int* saveError) {
    ssize_t n = ::write(fd, peek(), readableBytes());
    if(n < 0) {
        *saveError = errno;
    }
    return n;
}

}